home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group00a.txt / 000034_icon-group-sender _Tue Feb 15 13:07:26 2000.msg < prev    next >
Internet Message Format  |  2001-01-03  |  7KB

  1. Return-Path: <icon-group-sender>
  2. Received: (from root@localhost)
  3.     by baskerville.CS.Arizona.EDU (8.9.1a/8.9.1) id NAA19253
  4.     for icon-group-addresses; Tue, 15 Feb 2000 13:06:58 -0700 (MST)
  5. Message-Id: <200002152006.NAA19253@baskerville.CS.Arizona.EDU>
  6. X-Authentication-Warning: agate.berkeley.edu: news set sender to <news> using -f
  7. From: Jerry Leichter <leichter@smarts.com>
  8. X-Newsgroups: comp.lang.icon
  9. Subject: Re: Co-expressions and backtracking in Icon (& Scheme)
  10. Date: Tue, 15 Feb 2000 11:31:52 -0500
  11. X-Trace: versa.smarts.com 950632312 3856 198.49.114.99 (15 Feb 2000 16:31:52 GMT)
  12. X-Complaints-To: usenet@news.smarts.com
  13. To: John Paolillo <johnp@ling.uta.edu>
  14. To: icon-group@optima.CS.Arizona.EDU
  15. Errors-To: icon-group-errors@optima.CS.Arizona.EDU
  16. Status: RO
  17.  
  18. | ...The repeated mention of backtracking and co-routines
  19. | in conjunction with one another, and the sudden
  20. | realization that they may be similar in important ways
  21. | (saving a computational state to resume its computation
  22. | later), makes me wonder whether one might be able
  23. | to implement backtracking with co-expressions (seems
  24. | plausible, not that you would want to) and whether
  25. | they share some aspect of their implementation in Icon.
  26. | Can anyone explain the relationship between the two
  27. | in Icon?  And can anyone speak to the relationship
  28. | between the control aparatus of Scheme and that of
  29. | Icon?
  30.  
  31. You are asking about complex issues about which many papers have been
  32. written over many years.
  33.  
  34. Let's first look at backtracking and co-expressions.
  35.  
  36. Starting in the late 1960's, Ralph Griswold (and others) developed a
  37. serious of languages named SNOBOL; the last and most successful was
  38. SNOBOL4 (which is still available).  SNOBOL was based on pattern
  39. matching, which required full backtracking.  (The string analysis
  40. routines of Icon model the original SNOBOL string matching.)  SNOBOL was
  41. fully interpreted in the original implementation (though partially
  42. compiled implementations came later).  It used two stacks to implement
  43. pattern matching.
  44.  
  45. In (I think) the late '70's, Griswold developed an experiment language
  46. called SL5.  SL5 was inspired by a different approach to handling
  47. backtracking:  It used coroutines.  (A coroutine is like a function, but
  48. instead of simply returning, it can "suspend".  Later, you can "resume"
  49. the coroutine where it last suspended.  This has a bit of a similarity
  50. to multiple threads, but the usage is entirely different:  Only one
  51. coroutine ever runs at a time, and all transfers of control are
  52. explicitly programmed.)  Using coroutines, one could re-implement all
  53. the SNOBOL pattern matching stuff in a very general and powerful way.
  54. (SL5 also generalized a number of other ideas that were in SNOBOL, such
  55. as "I/O bound variables".  But those are not of real interest here.)
  56. Using the same general framework, one could use SL5 to go general
  57. backtracking as well.
  58.  
  59. SL5 was an experiment to see how far one could push these ideas.  Icon
  60. had its genesis in picking out some of the ideas in SL5 that had proved
  61. to be useful.  Also, it was found that there was a much more efficient
  62. way to implement those pieces of the coroutine model actually needed for
  63. backtracking using stack manipulation.  This became the basis of the
  64. Icon approach to backtracking.  (Actually, there was a short-lived
  65. experimental language called CG - C with Generators - that provided
  66. generators in C using the same stack manipulation trick.)  Icon focused
  67. on fully integrating the backtracking model - and string scanning, the
  68. algorithm that originally inspired it - into the rest of the language.
  69. (In SNOBOL, you essentially had a goal-directed pattern matching
  70. language embedded in a traditional imperative language.)  In fact,
  71. coexpressions - a form of coroutine control bound to syntactic
  72. expressions, rather than function calls - weren't in the original
  73. version of Icon; they were added a number of years later.  Yes, you
  74. could implement backtracking using coexpressions - that's going back to
  75. the original SL5 model.  However, the result wouldn't be particularly
  76. efficient.
  77.  
  78. Scheme and its continuations is the product of yet another long
  79. evolution.  I won't try to go into a full history here; rather, I'll
  80. suummarize what a continuation is.  (This is my own description; others
  81. describe it in different ways.)  Think about what happens when you call
  82. a function.  First, arguments are pushed on the stack.  Then control is
  83. transfered to the function.  It computes, and eventually returns.
  84.  
  85. Well, actually, the implementation has to do more:  For return to work,
  86. before transfering control, it has to pass the address to return to.
  87. Let's make that explicit:  Let's pretend the return address is passed as
  88. another argument.  Rather than a return, we just "go to" the return
  89. address.  That *almost* simulates the effect of return.  The problem is
  90. that the stack also has to be restored to what it was before the
  91. function was called.  Implementations do that implicitly - they either
  92. know how much space to clear off the stack, or save the actual old stack
  93. address.  So let's make *that* explicit, to:  Pass as an argument a
  94. special data structure, called a closure, that contains both the address
  95. at which to continue, and what the stack should be set to.  (The reason
  96. this is called a "closure" is that it "closes up" all the information
  97. needed to continue execution of a function from where it was.  In fact,
  98. that - not a pair of addresses - is the definition of a closure; real
  99. implementations may need to worry about saving other machine state.)
  100.  
  101. So far, we've just come up with fancy names for things without adding
  102. anything real to the language.  Things get interesting when we allow a
  103. program to *save* one of these closure objects - and invoke it
  104. repeatedly.  The result is very much like a coroutine (or coexpression)
  105. - and it turns out that it's extremely powerful.  It also leads to
  106. virtually incomprehensible programs unless very, very carefully used. 
  107. Usually, if you see a piece of code like:
  108.  
  109.     f();
  110.     g();
  111.     return;
  112.  
  113. you can reason that first f() is called, then g() is called, then we
  114. return.  But if f() can "capture" the closure at its return point -
  115. known as its continuation - then code elsewhere could jump back at the
  116. call to g() any number of times, without f() running again.
  117.  
  118. Generally, explicit use of closures and continuations is discouraged as
  119. a result:  They get used heavily inside of macros and as a compiler
  120. technique, but few Scheme users ever use call-cc (call with current
  121. continuation, which makes the current continuation into an explicit
  122. argument).  However, it *is* possible to use these techniques to do what
  123. arbitrary coroutines could do, including backtracking and generators.
  124.  
  125.                             -- Jerry
  126.